/**
 * 
 */
package com.util.orm.dao;

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.MyBatisExceptionTranslator;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.dao.support.PersistenceExceptionTranslator;

import java.lang.reflect.Field;

/**
 * 由于父类SqlSessionTemplate没有实现批处理的 commit, rollback 逻辑，所以复写此类。
 */
public class BatchSqlSessionTemplate extends SqlSessionTemplate {
	protected SqlSession superSqlSession;

    public BatchSqlSessionTemplate(SqlSessionTemplateRouter sqlSessionTemplateRouter, String key) {
		this(sqlSessionTemplateRouter.getSqlSessionTemplate(key).getSqlSessionFactory(),
				sqlSessionTemplateRouter.getSqlSessionTemplate(key).getExecutorType(),
				sqlSessionTemplateRouter.getSqlSessionTemplate(key).getPersistenceExceptionTranslator());
	}

	/**
	 * @param sqlSessionFactory
	 */
	public BatchSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
		  this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
	}

	/**
	 * @param sqlSessionFactory
	 * @param executorType
	 */
	public BatchSqlSessionTemplate(SqlSessionFactory sqlSessionFactory,ExecutorType executorType) {
		this(sqlSessionFactory, executorType,new MyBatisExceptionTranslator(
	            sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true));
	}

	/**
	 * BatchSqlSessionTemplate
	 * @param sqlSessionFactory
	 * @param executorType
	 * @param exceptionTranslator
	 */
	public BatchSqlSessionTemplate(SqlSessionFactory sqlSessionFactory,
			ExecutorType executorType,
			PersistenceExceptionTranslator exceptionTranslator) {
		super(sqlSessionFactory, executorType, exceptionTranslator);
		//从父类私有field中获取 sqlSessionProxy 并赋给 
		try {
			Field field = SqlSessionTemplate.class.getDeclaredField("sqlSessionProxy");
			field.setAccessible(true);
			this.superSqlSession = (SqlSession) field.get(this);
			
		} catch (Exception e) {
			throw new RuntimeException("BatchSqlSessionTemplate couldn't be inited, because super calss's field 'sqlSessionProxy' couldn't be got! " + e);
		}
	}
	
	@Override
	public void commit() {
		superSqlSession.commit();
	}
	
	public void commit(boolean force) {
		superSqlSession.commit(force);
	}
	
	@Override
	public void rollback() {
		superSqlSession.rollback();
	}
	
	@Override
	public void rollback(boolean force) {
		superSqlSession.rollback(force);
	}
}
